home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #1 / Amiga Plus CD - 1997 - No. 01.iso / pd / sonstiges / spontimag10 / magnet.cpp < prev    next >
C/C++ Source or Header  |  1996-10-15  |  6KB  |  259 lines

  1. /****** Magnet.cpp ***********************************************
  2. *
  3. *   PROGRAM
  4. *      Magnet
  5. *
  6. *   CONTENTS
  7. *      Simulates spontaneous magnetization by spin-flipping.
  8. *
  9. *   AUTHOR
  10. *      Georg Pfundt
  11. *
  12. *   COPYRIGHT
  13. *      © by Georg Pfundt   14-OCT-1996
  14. *
  15. *   LANGUAGE
  16. *      ANSI-C++
  17. *
  18. *   TRANSLATOR
  19. *      SAS-C V6.55
  20. *
  21. *   HISTORY
  22. *      1.0, GeP, 14-OCT-1996, first version
  23. *
  24. *   SUPPORT
  25. *      Dietrich Stauffer; "Theoretische Physik :  ein Kurzlehrbuch und
  26. *      Repetitorium", Springer Verlag Berlin, Heidelberg, New York, 1989.
  27. *      ISBN 3-540-50697-7 (Berlin ...),  ISBN 0-387-50697-7 (New York ...)
  28. *
  29. *   IMPORTS
  30. *      None.
  31. *
  32. *   BUGS
  33. *      None known.
  34. *
  35. *   ADDRESS
  36. *      Georg Pfundt, Im Oberviertel 18, 76229 Karlsruhe, Germany
  37. *
  38. *   PHONE
  39. *      +49 (0)721/481591
  40. *      E-Mail: gp@ict.fhg.de
  41. *
  42. *   DISCLAIMER
  43. *      This program is PUBLIC DOMAIN, as far as it is not used for
  44. *      military purposes!
  45. *
  46. ********************************************************************
  47. * TABSIZE=2
  48. */
  49.  
  50.  
  51. #include "OWindow.h"
  52. #include <exec/types.h>
  53. #include <proto/Graphics.h>
  54. #include <graphics/rpattr.h>
  55. #include <stdlib.h>
  56. #include <strstream.h>
  57. #include <fstream.h>
  58.  
  59.  
  60. /* External libbases for autoinitialisation */
  61. extern struct IntuitionBase *IntuitionBase;
  62. extern struct GfxBase *GfxBase;
  63.  
  64.  
  65. const char *version = "$VER: Magnet V1.0 by Georg Pfundt " __AMIGADATE__ "\n";
  66.  
  67.  
  68. int
  69. main(int argc, char *argv[])
  70. {
  71.   const char *usage =
  72.             "Magnet (C) by Georg Pfundt "__AMIGADATE__"\n"
  73.             "Usage: Magnet [-w width] [-h height] [-l level] [-?] [?]\n"
  74.             "width and height are the outer window sizes (default 100 x 110)\n"
  75.             "level is the initial magnetization level in permille (default 100=10%)\n"
  76.             "-? and ? give this help.\n\n";
  77.  
  78.     // options w and h are width and height
  79.     char *opts = "whl",option,*odata;
  80.     int next=1;
  81.  
  82.   // Default values for window size
  83.   WORD wwidth=100,wheight=110;
  84.     LONG level=100;
  85.  
  86.     while ((odata = argopt(argc,argv,opts,&next,&option)) != NULL)
  87.     {
  88.         switch (option)
  89.         {
  90.             case 'w':
  91.             {
  92.                 istrstream istr(odata);
  93.                 istr >> wwidth;
  94.             }
  95.             break;
  96.             case 'h':
  97.             {
  98.                 istrstream istr(odata);
  99.                 istr >> wheight;
  100.             }
  101.             case 'l':
  102.             {
  103.                 istrstream istr(odata);
  104.                 istr >> level;
  105.             }
  106.             break;
  107.             case '?':
  108.         cerr << usage;
  109.         return 5;
  110.         break;
  111.             default:
  112.                 cerr << "Ignored unknown Option \"-" << option << ' ' << odata
  113.                          << '\"' << endl;
  114.         }
  115.     }
  116.  
  117.     // check for help
  118.     if (*argv[next] == '?')
  119.   {
  120.     cerr << usage;
  121.     return 5;
  122.   }
  123.  
  124.  
  125.   // Check range of level
  126.   level = (level>1000 ? 1000 : level) < 0 ? 0 : level;
  127.  
  128.     // Check range for size
  129.   wwidth = (WORD)(wwidth < 0 ? 0x7fff : wwidth);
  130.   wheight = (WORD)(wheight < 0 ? 0x7fff : wheight);
  131.     wwidth = (WORD)(wwidth < 100 ? 100 : wwidth);
  132.     wheight = (WORD)(wheight < 80 ? 80 : wheight);
  133.  
  134.  
  135.   // Threshold for random numbers
  136.   LONG thresh = (((LONG)RAND_MAX & 0xfffffL)*level)/1000;
  137.  
  138.   //cerr << "Parameter: wxh= " << wwidth << " x " << wheight << "  level="
  139.   //     << level << "  thresh=" << thresh << endl;
  140.  
  141.   // Construct a Window for output
  142.   OWindow mywin("Spontaneous Magnetisation",wwidth,wheight,100,100);
  143.   if (!(mywin.IsOK()))
  144.   {
  145.     cerr << "Error opening Window!" << endl;
  146.     return 20;
  147.   }
  148.  
  149.  
  150.   // Get Actuall window dimensions
  151.   WORD fwidth=mywin.GetInnerWidth(),fheight=mywin.GetInnerHeight();
  152.  
  153.   // Get offsets
  154.   WORD x,y,xof,yof;
  155.   xof = mywin.GetLeftOffset();
  156.   yof = mywin.GetTopOffset();
  157.  
  158.   // Get actual font
  159.     struct TextFont *font;
  160.     GetRPAttrs(mywin.RP,RPTAG_Font,&font,TAG_END);
  161.  
  162.     // font size
  163.     struct TextExtent texex;
  164.     FontExtent(font,&texex);
  165.     // reduce height
  166.     fheight -= texex.te_Height;
  167.  
  168.     // text position
  169.     LONG textx = 5 + texex.te_Extent.MinX + xof;
  170.     LONG texty = fheight - texex.te_Extent.MinY + yof;
  171.   // Text buffer
  172.   char buf[40];
  173.     ostrstream ostr(buf,40);
  174.     ostr << "Magnet=";
  175.   // write-position
  176.   int pos = ostr.pcount();
  177.  
  178.  
  179.   // Set for black and white
  180.   SetMaxPen(mywin.RP,1L);
  181.   SetWriteMask(mywin.RP,1);
  182.   // Set Color and drawing mode
  183.   SetABPenDrMd(mywin.RP,1L,0L,JAM1);
  184.  
  185.   // Initalize the screen by random dots
  186.  
  187.     //initial seed for random number
  188.   srand((LONG)argv);
  189.  
  190.   LONG magnet=0L;
  191.  
  192.     y=(WORD)(fheight- 1 + yof);
  193.     while(--y > yof)
  194.     {
  195.         x=(WORD)(fwidth- 1 + xof);
  196.         while (--x > xof)
  197.             if ((rand() & 0xfffffL) <= thresh)
  198.             {
  199.                 WritePixel(mywin.RP,x,y);
  200.                 magnet--;
  201.             }
  202.             else
  203.                 magnet++;
  204.     }
  205.  
  206.   const LONG rand_max = RAND_MAX & 0xfffffL;
  207.  
  208.   // Check for new event
  209.     while (mywin.CheckMessage() != OWindow::OW_Close)
  210.     {
  211.         // Output magnetisation
  212.         LONG mag2 = (magnet*1000L+500L)/(fwidth-2)/(fheight-2);
  213.         ostr.rdbuf()->seekoff(pos,ios::beg);
  214.         ostr << (mag2 / 10L) << '.' << ((mag2 < 0 ? -mag2 : mag2) % 10)
  215.                 << "% ";
  216.  
  217.     // Get textextent
  218.     int chars =
  219.             TextFit(mywin.RP,ostr.str(),ostr.pcount()-1,&texex,NULL,1,fwidth-10,fheight);
  220.  
  221.         // Write text
  222.         SetDrMd(mywin.RP,JAM2);
  223.         Move(mywin.RP,textx,texty);
  224.  
  225.     // If text too wide reduce it
  226.     if (chars < (ostr.pcount()-1))
  227.     {
  228.         chars = TextFit(mywin.RP,ostr.str()+pos,ostr.pcount()-pos-2,&texex,NULL,
  229.                                             1,fwidth-10,fheight);
  230.             Text(mywin.RP,ostr.str()+pos,chars);
  231.     }
  232.     else
  233.             Text(mywin.RP,ostr.str(),chars);
  234.  
  235.         // Unlock Streambuf
  236.         ostr.rdbuf()->freeze(0);
  237.  
  238.  
  239.         // Set Drawmode to XOR
  240.         SetDrMd(mywin.RP,COMPLEMENT);
  241.     // Loop 3000 pixels
  242.         WORD i=3000;
  243.         while (i--)
  244.         {
  245.             x = (WORD)(((rand() & 0xfffffL) * (fwidth-2))/rand_max+xof+1);
  246.             y = (WORD)(((rand() & 0xfffffL) * (fheight-2))/rand_max+yof+1);
  247.             if (ReadPixel(mywin.RP,x-1,y) + ReadPixel(mywin.RP,x+1,y) +
  248.                     ReadPixel(mywin.RP,x,y-1) + ReadPixel(mywin.RP,x,y+1) == 2)
  249.             {
  250.                 magnet += (ReadPixel(mywin.RP,x,y) << 1) - 1;
  251.                 WritePixel(mywin.RP,x,y);
  252.             }
  253.         }
  254.     }
  255.  
  256.  
  257.     return 0;
  258. }
  259.